<template>
    <view class="tui-cascade-selection">
        <scroll-view
            scroll-x
            scroll-with-animation
            :scroll-into-view="scrollViewId"
            :style="{ backgroundColor: headerBgColor }"
            class="tui-bottom-line"
            :class="{ 'tui-btm-none': !headerLine }"
        >
            <view
                class="tui-selection-header"
                :style="{
                    height: tabsHeight,
                    backgroundColor: backgroundColor
                }"
            >
                <view
                    class="tui-header-item"
                    :class="{ 'tui-font-bold': index === currentTab && bold }"
                    :style="{
                        color: index === currentTab ? activeColor : color,
                        fontSize: size + 'rpx'
                    }"
                    :id="`id_${index}`"
                    @tap.stop="swichNav"
                    :data-current="index"
                    v-for="(item, index) in selectedArr"
                    :key="index"
                >
                    {{ item.text }}
                    <view
                        class="tui-active-line"
                        :style="{ backgroundColor: lineColor }"
                        v-if="index === currentTab && showLine"
                    ></view>
                </view>
            </view>
        </scroll-view>
        <swiper
            class="tui-selection-list"
            :current="currentTab"
            duration="300"
            @change="switchTab"
            :style="{ height: height, backgroundColor: backgroundColor }"
        >
            <swiper-item v-for="(item, index) in selectedArr" :key="index">
                <scroll-view
                    scroll-y
                    :scroll-into-view="item.scrollViewId"
                    class="tui-selection-item"
                    :style="{ height: height }"
                >
                    <view
                        class="tui-first-item"
                        :style="{ height: firstItemTop }"
                    ></view>
                    <view
                        class="tui-selection-cell"
                        :style="{
                            padding: padding,
                            backgroundColor: backgroundColor
                        }"
                        :id="`id_${subIndex}`"
                        v-for="(subItem, subIndex) in item.list"
                        :key="subIndex"
                        @tap="change(index, subIndex, subItem)"
                    >
                        <icon
                            type="success_no_circle"
                            v-if="item.index === subIndex"
                            :color="checkMarkColor"
                            :size="checkMarkSize"
                            class="tui-icon-success"
                        ></icon>
                        <image
                            :src="subItem.src"
                            v-if="subItem.src"
                            class="tui-cell-img"
                            :style="{
                                width: imgWidth,
                                height: imgHeight,
                                borderRadius: radius
                            }"
                        ></image>
                        <view
                            class="tui-cell-title"
                            :class="{
                                'tui-font-bold':
                                    item.index === subIndex && textBold,
                                'tui-flex-shrink': nowrap
                            }"
                            :style="{
                                color:
                                    item.index === subIndex
                                        ? textActiveColor
                                        : textColor,
                                fontSize: textSize + 'rpx'
                            }"
                        >
                            {{ subItem.text }}
                        </view>
                        <view
                            class="tui-cell-sub_title"
                            :style="{
                                color: subTextColor,
                                fontSize: subTextSize + 'rpx'
                            }"
                            v-if="subItem.subText"
                            >{{ subItem.subText }}</view
                        >
                    </view>
                </scroll-view>
            </swiper-item>
        </swiper>
    </view>
</template>

<script>
export default {
    name: 'tuiCascadeSelection',
    props: {
        /**
			 * 如果下一级是请求返回，则为第一级数据，否则所有数据
			 * 数据格式
			  [{
				  src: "",
				  text: "",
				  subText: "",
				  value: 0,
				  children:[{
					  text: "",
					  subText: "",
					  value: 0,
					  children:[]
			   }]
			  }]
			 * */
        itemList: {
            type: Array,
            default: () => {
                return []
            }
        },
        /*
		   初始化默认选中数据
		   [{
			text: "",//选中text
			subText: '',//选中subText
			value: '',//选中value
			src: '', //选中src，没有则传空或不传
			index: 0, //选中数据在当前layer索引
			list: [{src: "", text: "", subText: "", value: 101}] //所有layer数据集合
		  }];
		    
		   */
        defaultItemList: {
            type: Array,
            value: []
        },
        //是否显示header底部细线
        headerLine: {
            type: Boolean,
            default: true
        },
        //header背景颜色
        headerBgColor: {
            type: String,
            default: '#FFFFFF'
        },
        //顶部标签栏高度
        tabsHeight: {
            type: String,
            default: '88rpx'
        },
        //默认显示文字
        text: {
            type: String,
            default: '请选择'
        },
        //tabs 文字大小
        size: {
            type: Number,
            default: 28
        },
        //tabs 文字颜色
        color: {
            type: String,
            default: '#555'
        },
        //选中颜色
        activeColor: {
            type: String,
            default: '#5677fc'
        },
        //选中后文字加粗
        bold: {
            type: Boolean,
            default: true
        },
        //选中后是否显示底部线条
        showLine: {
            type: Boolean,
            default: true
        },
        //线条颜色
        lineColor: {
            type: String,
            default: '#5677fc'
        },
        //icon 大小
        checkMarkSize: {
            type: Number,
            default: 15
        },
        //icon 颜色
        checkMarkColor: {
            type: String,
            default: '#5677fc'
        },
        //item 图片宽度
        imgWidth: {
            type: String,
            default: '40rpx'
        },
        //item 图片高度
        imgHeight: {
            type: String,
            default: '40rpx'
        },
        //图片圆角
        radius: {
            type: String,
            default: '50%'
        },
        //item text颜色
        textColor: {
            type: String,
            default: '#333'
        },
        textActiveColor: {
            type: String,
            default: '#333'
        },
        //选中后字体是否加粗
        textBold: {
            type: Boolean,
            default: true
        },
        //item text字体大小
        textSize: {
            type: Number,
            default: 28
        },
        //text 是否不换行
        nowrap: {
            type: Boolean,
            default: false
        },
        //item subText颜色
        subTextColor: {
            type: String,
            default: '#999'
        },
        //item subText字体大小
        subTextSize: {
            type: Number,
            default: 24
        },
        // item padding
        padding: {
            type: String,
            default: '20rpx 30rpx'
        },
        //占位高度，第一条数据距离顶部距离
        firstItemTop: {
            type: String,
            default: '20rpx'
        },
        //swiper 高度
        height: {
            type: String,
            default: '300px'
        },
        //item  swiper 内容部分背景颜色
        backgroundColor: {
            type: String,
            default: '#FFFFFF'
        },
        //子集数据是否请求返回（默认false，一次性返回所有数据）
        request: {
            type: Boolean,
            default: false
        },
        //子级数据（当有改变时，默认当前选中项新增子级数据，request=true时生效）
        receiveData: {
            type: Array,
            default: () => {
                return []
            }
        },
        //改变值则重置数据
        reset: {
            type: [Number, String],
            default: 0
        }
    },
    watch: {
        itemList(val) {
            this.initData(val, -1)
        },
        receiveData(val) {
            this.subLevelData(val, this.currentTab)
        },
        reset() {
            this.initData(this.itemList, -1)
        },
        defaultItemList(val) {
            this.setDefaultData(val)
        }
    },
    created() {
        this.setDefaultData(this.defaultItemList)
    },
    data() {
        return {
            currentTab: 0,
            //tab栏scrollview滚动的位置
            scrollViewId: 'id__1',
            selectedArr: []
        }
    },
    methods: {
        setDefaultData(val) {
            let defaultItemList = val || []
            if (defaultItemList.length > 0) {
                defaultItemList.map(item => {
                    item.scrollViewId = `id_${item.index}`
                })
                this.selectedArr = defaultItemList
                this.currentTab = defaultItemList.length - 1
                this.$nextTick(() => {
                    this.checkCor()
                })
            } else {
                this.initData(this.itemList, -1)
            }
        },
        initData(data, layer) {
            if (!data || data.length === 0) return
            if (this.request) {
                //第一级数据
                this.subLevelData(data, layer)
            } else {
                let selectedValue = this.selectedValue || {}
                if (selectedValue.type) {
                    this.setDefaultData(selectedValue)
                } else {
                    this.subLevelData(this.getItemList(layer, -1), layer)
                }
            }
        },
        removeChildren(data) {
            let list = data.map(item => {
                delete item['children']
                return item
            })
            return list
        },
        getItemList(layer, index) {
            let list = []
            let arr = JSON.parse(JSON.stringify(this.itemList))
            if (layer == -1) {
                list = this.removeChildren(arr)
            } else {
                let value = this.selectedArr[0].index
                value = value == -1 ? index : value
                list = arr[value].children || []
                if (layer > 0) {
                    for (let i = 1; i < layer + 1; i++) {
                        let val =
                            layer === i ? index : this.selectedArr[i].index
                        list = list[val].children || []
                        if (list.length === 0) break
                    }
                }
                list = this.removeChildren(list)
            }
            return list
        },
        //滚动切换
        switchTab: function(e) {
            this.currentTab = e.detail.current
            this.checkCor()
        },
        //点击标题切换当
        swichNav: function(e) {
            let cur = e.currentTarget.dataset.current
            if (this.currentTab != cur) {
                this.currentTab = cur
            }
        },
        checkCor: function() {
            let item = this.selectedArr[this.currentTab]
            item.scrollViewId = 'id__1'
            this.$nextTick(() => {
                setTimeout(() => {
                    let val = item.index < 2 ? 0 : Number(item.index - 2)
                    item.scrollViewId = `id_${val}`
                }, 2)
            })

            if (this.currentTab > 1) {
                this.scrollViewId = `id_${this.currentTab - 1}`
            } else {
                this.scrollViewId = `id_0`
            }
        },
        change(index, subIndex, subItem) {
            let item = this.selectedArr[index]
            if (item.index == subIndex) return
            item.index = subIndex
            item.text = subItem.text
            item.value = subItem.value
            item.subText = subItem.subText || ''
            item.src = subItem.src || ''

            this.$emit('change', {
                layer: index,
                subIndex: subIndex, //layer=> Array index
                ...subItem
            })

            if (!this.request) {
                let data = this.getItemList(index, subIndex)
                this.subLevelData(data, index)
            }
        },
        //新增子级数据时处理
        subLevelData(data, layer) {
            if (!data || data.length === 0) {
                if (layer == -1) return
                //完成选择
                let result = JSON.parse(JSON.stringify(this.selectedArr))
                let lastItem = result[result.length - 1] || {}
                let text = ''
                result.map(item => {
                    text += item.text
                    delete item['list']
                    //delete item['index'];
                    delete item['scrollViewId']
                    return item
                })
                this.$emit('complete', {
                    result: result,
                    value: lastItem.value,
                    text: text,
                    subText: lastItem.subText,
                    src: lastItem.src
                })
            } else {
                //重置数据（ >layer层级）
                let item = [
                    {
                        text: this.text,
                        subText: '',
                        value: '',
                        src: '',
                        index: -1,
                        scrollViewId: 'id__1',
                        list: data
                    }
                ]
                if (layer == -1) {
                    this.selectedArr = item
                } else {
                    let retainArr = this.selectedArr.slice(0, layer + 1)
                    this.selectedArr = retainArr.concat(item)
                }
                this.$nextTick(() => {
                    this.currentTab = this.selectedArr.length - 1
                })
            }
        }
    }
}
</script>

<style scoped>
.tui-cascade-selection {
    width: 100%;
    box-sizing: border-box;
}

.tui-selection-header {
    width: 100%;
    display: flex;
    align-items: center;
    position: relative;
    box-sizing: border-box;
}

.tui-bottom-line {
    position: relative;
}

.tui-bottom-line::after {
    width: 100%;
    content: '';
    position: absolute;
    border-bottom: 1rpx solid #eaeef1;
    -webkit-transform: scaleY(0.5) translateZ(0);
    transform: scaleY(0.5) translateZ(0);
    transform-origin: 0 100%;
    bottom: 0;
    right: 0;
    left: 0;
}

.tui-btm-none::after {
    border-bottom: 0 !important;
}

.tui-header-item {
    max-width: 240rpx;
    padding: 15rpx 30rpx;
    box-sizing: border-box;
    flex-shrink: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    position: relative;
}

.tui-font-bold {
    font-weight: bold;
}

.tui-active-line {
    width: 60rpx;
    height: 6rpx;
    border-radius: 4rpx;
    position: absolute;
    bottom: 0;
    right: 0;
    left: 50%;
    transform: translateX(-50%);
}

.tui-selection-cell {
    width: 100%;
    box-sizing: border-box;
    display: flex;
    align-items: center;
}

.tui-icon-success {
    margin-right: 12rpx;
}

.tui-cell-img {
    margin-right: 12rpx;
    flex-shrink: 0;
}

.tui-cell-title {
    word-break: break-all;
}

.tui-flex-shrink {
    flex-shrink: 0;
}

.tui-font-bold {
    font-weight: bold;
}

.tui-cell-sub_title {
    margin-left: 20rpx;
    word-break: break-all;
}
.tui-first-item {
    width: 100%;
}
</style>
